package com.lobov.utils;

import java.util.Random;

import com.lobov.entities.Matrix;
import com.lobov.entities.yale.MatrixYale;
import com.lobov.entities.yale.SparseVector;

/**
 * Генератор матриц (утильный класс)
 */
public class Generator {

	/**
	 * Сгенерировать разреженную матрицу с заданным количеством столбцов и строк
	 * 
	 * @param xLength
	 *            столбцов матрицы
	 * @param yLength
	 *            строк матрицы
	 * @return возвращает полностью проинициализированный объект типа Matrix
	 */
	public static Matrix generateUnCompressedHorisontalMatrix(int xLength,
			int yLength, double density) {
		Matrix matrix = new Matrix(xLength, yLength);
		double[] values = new double[xLength * yLength];
		int[] xs = new int[xLength * yLength];
		int[] ys = new int[xLength * yLength];
		int counter = 0;
		for (int y = yLength; y > 0; y--) {
			for (int x = xLength; x > 0; x--) {
				values[counter] = getDouble(density);
				xs[counter] = x;
				ys[counter] = y;
				counter++;
			}
		}
		matrix.setValues(values);
		matrix.setXs(xs);
		matrix.setYs(ys);
		return matrix;
	}

	public static MatrixYale generateUnCompressedHorisontalMatrixYale(
			int xLength, int yLength, double density) {
		SparseVector[] vectors = new SparseVector[yLength];
		for (int i = 0; i < yLength; i++) {
			vectors[i] = generateVector(xLength, i, density);
		}
		return new MatrixYale(vectors, false);
	}

	private static SparseVector generateVector(int xLength, int yPosition, double density) {
		double[] values = new double[xLength];
		for (int i = 0; i < xLength; i++) {
			values[i] = getDouble(density);
		}
		return new SparseVector(xLength, yPosition, values, null, false);
	}
	
	public static SparseVector generateEmptyVector(int xLength, int yPosition) {
		double[] values = new double[xLength];
		return new SparseVector(xLength, yPosition, values, null, false);
	}

	private static double getDouble(double density) {
		double sign = 1d;
		if (Math.random() < 0.5) { // определяет 50%-но знак числа (+/-)
			sign *= -1d;
		}
		if (Math.random() < density) { // определяет 20%-ную заполненность матрицы
			return new Random().nextDouble() * sign;
		} else {
			return 0;
		}
	}
	
	public static MatrixYale generateUnCompressedHorisontalMatrixYaleEmty(
			int xLength, int yLength, double density) {
		SparseVector[] vectors = new SparseVector[yLength];
		for (int i = 0; i < yLength; i++) {
			vectors[i] = generateVector(xLength, i, density);
		}
		return new MatrixYale(vectors, false);
	}
}
